import type { ChatResponse } from '@/api/interface'

// 聊天服务类
export class ChatService {
  private eventSource: EventSource | null = null
  private chatId: string | null = null
  private roleId: string | null = null
  private onMessageCallback?: (data: ChatResponse) => void
  private onErrorCallback?: (error: Event) => void
  private errorCount: number = 0
  private readonly maxRetries: number = 2
  private lastRawEmitted: string = ''
  private isCompleted: boolean = false

  // 初始化聊天
  initChat(roleId: string, chatId?: string) {
    this.roleId = roleId
    // 为便于联调验证后端响应，临时将 chatId 固定为 chat_123456。
    // 若传入自定义 chatId 则优先使用传入值。
    this.chatId = chatId || 'chat_123456'
    return this.chatId
  }

  // 生成聊天ID
  private generateChatId(): string {
    return `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  // 发送消息：直接通过 SSE 建立含 userInput 的连接（发送 + 接收合并为一条流）
  async sendMessage(userInput: string): Promise<void> {
    if (!this.chatId || !this.roleId) {
      
      throw new Error('聊天未初始化')
    }

    // 若已有连接，先关闭，避免并发两个流
    if (this.eventSource) {
      this.eventSource.close()
      this.eventSource = null
    }

    // reset retry and state flags
    this.errorCount = 0
    this.lastRawEmitted = ''
    this.isCompleted = false

    const baseURL = import.meta.env.VITE_APP_BASE_API || 'http://22600428.r9.vip.cpolar.cn'
    // 使用 encodeURIComponent 避免特殊字符破坏查询串
    const encodedInput = encodeURIComponent(userInput)
    const characterId = this.roleId ?? ''
    const sseUrl = `${baseURL}/roleChat/streamChat?userInput=${encodedInput}&chatId=${this.chatId}&characterId=${characterId}`

    try {
      this.openEventSource(sseUrl)

      // 兼容两种后端格式：
      // 1) 直接按字符切分（data: 哈 \n data: 喽 ...）
      // 2) 标准 JSON 包装（{type:'llm.partial', text:'...'}）
      this.eventSource!.onmessage = (event) => {
        this.handleIncomingRaw(event.data)
      }

      // 兼容自定义事件：event: text
      this.eventSource!.addEventListener('text', (event: MessageEvent) => {
        this.handleIncomingRaw(event.data)
      })

      // 图片相关事件：event: imageStatus（JSON），event: images（JSON 数组或字符串数组）
      this.eventSource!.addEventListener('imageStatus', (event: MessageEvent) => {
        try {
          
          const parsed = JSON.parse(event.data)
          this.onMessageCallback?.({
            type: 'imageStatus' as any,
            content: '',
            chatId: this.chatId as string,
            imageStatus: {
              imagePrompt: parsed?.imagePrompt,
              needImage: !!parsed?.needImage,
            },
          })
        } catch (e) {
          
        }
      })

      // 兼容旧版：event: images （JSON 数组或 {images:[]}）
      this.eventSource!.addEventListener('images', (event: MessageEvent) => {
        try {
          
          let images: string[] = []
          try {
            const data = JSON.parse(event.data)
            images = Array.isArray(data) ? data : (Array.isArray(data?.images) ? data.images : [])
          } catch (_) {
            // 不是 JSON，则当作单个 URL 字符串
            const url = String(event.data || '').trim()
            if (url) images = [url]
          }
          if (images && images.length > 0) {
            this.onMessageCallback?.({
              type: 'images' as any,
              content: '',
              chatId: this.chatId as string,
              images,
            })
          }
        } catch (e) {
          
        }
      })

      // 新版：event: image （直接返回图片 URL 字符串）
      this.eventSource!.addEventListener('image', (event: MessageEvent) => {
        try {
          const url = String(event.data || '').trim()
          if (url) {
            this.onMessageCallback?.({
              type: 'images' as any,
              content: '',
              chatId: this.chatId as string,
              images: [url],
            })
          }
        } catch (e) {
          
        }
      })

      this.eventSource!.onerror = (error) => {
        // 检查是否是敏感词错误（通过error事件传递的错误消息）
        if (error && (error as any).data) {
          const errorData = (error as any).data
          if (errorData.includes('很抱歉') || errorData.includes('不符合') || errorData.includes('规范')) {
            // 将错误消息作为正常消息处理
            this.onMessageCallback?.({
              type: 'error' as any,
              content: errorData,
              chatId: this.chatId as string,
            })
            this.close()
            return
          }
        }
        
        this.onErrorCallback?.(error)
        // 对于流式对话的单次请求，不做自动重连，避免重复发送与多次SSE连接
        this.close()
      }
    } catch (error) {
      
      throw error
    }
  }

  // 统一的消息处理逻辑：支持 JSON/纯文本与完成标记
  private handleIncomingRaw(raw: string) {
    // 空包或 keepalive 直接忽略
    if (!raw || raw === 'null') return

    // 标准结束标记，关闭连接并通知完成
    if (raw === '[DONE]') {
      this.onMessageCallback?.({
        type: 'complete' as any,
        content: '',
        chatId: this.chatId as string,
      })
      this.isCompleted = true
      this.close()
      return
    }

    try {
      const parsed: any = JSON.parse(raw)
      // 如果能被解析为 JSON，按后端的字段透传给 UI
      this.onMessageCallback?.(parsed as ChatResponse)
      // 若后端通过 type/event 表示完成，收到后关闭连接
      const endFlags = [parsed?.type, parsed?.event]
      if (endFlags.some((v: any) => typeof v === 'string' && /complete|done|finish/i.test(v))) {
        this.isCompleted = true
        this.close()
      }
      return
    } catch (_) {
      // 不是 JSON，检查是否是错误消息
      if (raw.includes('很抱歉') || raw.includes('不符合') || raw.includes('规范')) {
        // 识别为错误消息
        this.onMessageCallback?.({
          type: 'error' as any,
          content: raw,
          chatId: this.chatId as string,
        })
        return
      }
      
      // 当作纯文本增量
      // 简单去重：与上一条完全相同则忽略（应对重连时重复片段）
      if (raw === this.lastRawEmitted) return
      this.onMessageCallback?.({
        // 约定一个最小的结构，供页面判断
        type: 'partial' as any,
        content: raw,
        chatId: this.chatId as string,
      })
      this.lastRawEmitted = raw
    }
  }

  // 打开 EventSource（封装，便于重连）
  private openEventSource(url: string) {
    this.eventSource = new EventSource(url)
  }

  // 启动SSE监听（旧逻辑已合并到 sendMessage，不再使用，保留空实现以兼容调用方）
  private startSSEListener() {}

  // 设置消息回调
  onMessage(callback: (data: ChatResponse) => void) {
    this.onMessageCallback = callback
  }

  // 设置错误回调
  onError(callback: (error: Event) => void) {
    this.onErrorCallback = callback
  }

  // 获取当前聊天ID
  getChatId(): string | null {
    return this.chatId
  }

  // 获取当前角色ID
  getRoleId(): string | null {
    return this.roleId
  }

  // 关闭连接
  close() {
    if (this.eventSource) {
      this.eventSource.close()
      this.eventSource = null
    }
  }

  // 销毁服务
  destroy() {
    this.close()
    this.chatId = null
    this.roleId = null
    this.onMessageCallback = undefined
    this.onErrorCallback = undefined
  }
}

// 创建单例实例
export const chatService = new ChatService()
